package cn.iocoder.yudao.framework.common.util.http;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.map.TableMap;
import cn.hutool.core.net.url.UrlBuilder;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.util.StringUtils;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;
import javax.servlet.http.HttpServletRequest;
import java.net.URI;
import java.nio.charset.Charset;
import java.util.Map;



/**
 * HTTP 工具类
 *
 * @author 芋道源码
 */
public class HttpUtils {

    @SuppressWarnings("unchecked")
    public static String replaceUrlQuery(String url, String key, String value) {
        UrlBuilder builder = UrlBuilder.of(url, Charset.defaultCharset());
        // 先移除
        TableMap<CharSequence, CharSequence> query = (TableMap<CharSequence, CharSequence>)
                ReflectUtil.getFieldValue(builder.getQuery(), "query");
        query.remove(key);
        // 后添加
        builder.addQuery(key, value);
        return builder.build();
    }

    private String append(String base, Map<String, ?> query, boolean fragment) {
        return append(base, query, null, fragment);
    }

    /**
     * 拼接 URL
     * <p>
     * copy from Spring Security OAuth2 的 AuthorizationEndpoint 类的 append 方法
     *
     * @param base     基础 URL
     * @param query    查询参数
     * @param keys     query 的 key，对应的原本的 key 的映射。例如说 query 里有个 key 是 xx，实际它的 key 是 extra_xx，则通过 keys 里添加这个映射
     * @param fragment URL 的 fragment，即拼接到 # 中
     * @return 拼接后的 URL
     */
    public static String append(String base, Map<String, ?> query, Map<String, String> keys, boolean fragment) {
        UriComponentsBuilder template = UriComponentsBuilder.newInstance();
        UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(base);
        URI redirectUri;
        try {
            // assume it's encoded to start with (if it came in over the wire)
            redirectUri = builder.build(true).toUri();
        } catch (Exception e) {
            // ... but allow client registrations to contain hard-coded non-encoded values
            redirectUri = builder.build().toUri();
            builder = UriComponentsBuilder.fromUri(redirectUri);
        }
        template.scheme(redirectUri.getScheme()).port(redirectUri.getPort()).host(redirectUri.getHost())
                .userInfo(redirectUri.getUserInfo()).path(redirectUri.getPath());

        if (fragment) {
            StringBuilder values = new StringBuilder();
            if (redirectUri.getFragment() != null) {
                String append = redirectUri.getFragment();
                values.append(append);
            }
            for (String key : query.keySet()) {
                if (values.length() > 0) {
                    values.append("&");
                }
                String name = key;
                if (keys != null && keys.containsKey(key)) {
                    name = keys.get(key);
                }
                values.append(name).append("={").append(key).append("}");
            }
            if (values.length() > 0) {
                template.fragment(values.toString());
            }
            UriComponents encoded = template.build().expand(query).encode();
            builder.fragment(encoded.getFragment());
        } else {
            for (String key : query.keySet()) {
                String name = key;
                if (keys != null && keys.containsKey(key)) {
                    name = keys.get(key);
                }
                template.queryParam(name, "{" + key + "}");
            }
            template.fragment(redirectUri.getFragment());
            UriComponents encoded = template.build().expand(query).encode();
            builder.query(encoded.getQuery());
        }
        return builder.build().toUriString();
    }

    public static String[] obtainBasicAuthorization(HttpServletRequest request) {
        String clientId;
        String clientSecret;
        // 先从 Header 中获取
        String authorization = request.getHeader("Authorization");
        authorization = StrUtil.subAfter(authorization, "Basic ", true);
        if (StringUtils.hasText(authorization)) {
            authorization = Base64.decodeStr(authorization);
            clientId = StrUtil.subBefore(authorization, ":", false);
            clientSecret = StrUtil.subAfter(authorization, ":", false);
            // 再从 Param 中获取
        } else {
            clientId = request.getParameter("client_id");
            clientSecret = request.getParameter("client_secret");
        }

        // 如果两者非空，则返回
        if (StrUtil.isNotEmpty(clientId) && StrUtil.isNotEmpty(clientSecret)) {
            return new String[]{clientId, clientSecret};
        }
        return null;
    }


    /**
     * 获取贝壳租房网搜索结果
     *
     * @param param 要搜索的关键字
     * @return 房源总价格
     */
    public static String getBkeHousingResForSearch(String param) {
        try {

            HttpUtils httpUtils = new HttpUtils();
            // 从URL获取HTML内容
            String html = HttpUtil.createGet("https://cq.ke.com/xiaoqu/rs" + param + "/")
                    //.header("cookie","hip=gsenNjmNpI_mIM-ScpTa2PQZG9uuvFSUEJONlJSE-Xuizpe8pj6bGomfX2PD36TNG80oOdXEKm_JyIAMF4J3l23bfZI3KGDqfucrfSKEdJMMbc4JdiBb47_zf7g-hAQVD476TXjNh30JbS53PaR8DdBYrjbLWmo39NrxBJHZQSr0SexAtLY%3D")
                    .header("cookie","lianjia_ssid=0d22904c-8a66-490c-b700-34b4863e553e; lianjia_uuid=dd967ea1-5eb5-4175-9d31-08c7d6980b9f; select_city=500000; HMACCOUNT=4E56DB5BCF10EECC; sajssdk_2015_cross_new_user=1; sensorsdata2015jssdkcross=%7B%22distinct_id%22%3A%22191c55d170f1263-07d81b9e9f24f3-17525637-2073600-191c55d17102644%22%2C%22%24device_id%22%3A%22191c55d170f1263-07d81b9e9f24f3-17525637-2073600-191c55d17102644%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22%E7%9B%B4%E6%8E%A5%E6%B5%81%E9%87%8F%22%2C%22%24latest_referrer%22%3A%22%22%2C%22%24latest_referrer_host%22%3A%22%22%2C%22%24latest_search_keyword%22%3A%22%E6%9C%AA%E5%8F%96%E5%88%B0%E5%80%BC_%E7%9B%B4%E6%8E%A5%E6%89%93%E5%BC%80%22%7D%7D; crosSdkDT2019DeviceId=-mzx64c--y3e1di-j86sphrvvvjkkmy-1dgs3jgns; lfrc_=ab5cfec2-f24c-45f9-80c2-f7bd10262dea; hip=GNH2bw_x312bP1V-eIJwWaayg_11bD8rvMGgVm5wBBBvRMyceHLEK0wI5VcbQ4_x5sX8Q5H5ckNXrAlgST8y671fAvtXwYNTYPsUrxs6-YV4aaTqPCKcCfpR-M9nZsAieCQX2FOwImTPS4azM-7KAqI9xryUeJky-WBHpTozApys4WwwHCU%3D; Hm_lvt_b160d5571570fd63c347b9d4ab5ca610=1725601946; Hm_lpvt_b160d5571570fd63c347b9d4ab5ca610=1725601979; srcid=eyJ0Ijoie1wiZGF0YVwiOlwiYzVmMzIzYjYyZjAyMGEyMjY0Zjk4MTMwMWZkN2RhZTViMzY0ZGVhNDRmY2I2NGRkYzYyY2ZlYzFjYTUwODk5NjZhMGU2ZDZhZDczZWFiZmQ2NGRhYWZlNTQxMGQ3MTljODQyNzU3YTJkNmY1M2NjM2EwMjAwNjMzNmYxOTdlMGUxMzA1ZjI3Nzc5YzMyZTIyM2I4ZjI0ZWUxNDIwZjNhMzEwNWZmM2JiM2UwN2UxNGUxMzI1NzcyM2M5YTVjYWEzODFkMDc4OGU5NWRkNGFkYjRiNjllYTYyMzQ5YzI3ZTdlMjc3M2I5ZTI3ZmE2MjdiYjYzMGVlYjRhM2ZkY2I0YVwiLFwia2V5X2lkXCI6XCIxXCIsXCJzaWduXCI6XCJhMDQ2OTc5MlwifSIsInIiOiJodHRwczovL2NxLmtlLmNvbS94aWFvcXUvcnMvIiwib3MiOiJ3ZWIiLCJ2IjoiMC4xIn0=; login_ucid=2000000101852215; lianjia_token=2.00106ea83b6ce7e1e001c3810a26494a32; lianjia_token_secure=2.00106ea83b6ce7e1e001c3810a26494a32; security_ticket=WKUTqd5+eqCnqvS11FyZUfj67P887+XhEKNygnMa9StzfNgvTlE4M6FL2SqJ548wE8KFL0kbnW1xX5rA98eiiuLa0uoM4CAdzO6UY60CgdJOWHuwhCq4TZKVydTS5xD0fZkAGTnEB98pZrVc8jBuxntPqZrO88/iDvp/6KFBN/4=")
                    .execute()
                    .body();

            // 使用Jsoup解析HTML
            Document doc = Jsoup.parse(html);

            // 获取页面中第一个<div>元素属性
            Element firstDiv = doc.getElementsByClass("totalPrice").first();
            Element classValue = firstDiv.getElementsByTag("span").first();

            // 输出结果
            return classValue.html();
        } catch (Exception e) {
            //log.error("获取到数据异常", e);
        }
        return "";
    }

    public static String getBkeHousingResForSearch2(String param) {
        try {

            HttpUtils httpUtils = new HttpUtils();
            // 从URL获取HTML内容
            String html = HttpUtil.createGet("https://cq.ke.com/xiaoqu/rs" + param + "/")
                    //.header("cookie","hip=gsenNjmNpI_mIM-ScpTa2PQZG9uuvFSUEJONlJSE-Xuizpe8pj6bGomfX2PD36TNG80oOdXEKm_JyIAMF4J3l23bfZI3KGDqfucrfSKEdJMMbc4JdiBb47_zf7g-hAQVD476TXjNh30JbS53PaR8DdBYrjbLWmo39NrxBJHZQSr0SexAtLY%3D")
                    //.header("cookie","hip=h1Dc1KHhGFZeez7PDglJ2Bu7ol5aAgAJpUL1z7eWXES9-LkOxh7LHliHkbcAo7FWg2YFEYVZVIiiotgVQP-N0xyKzu03jLSy25sdgfCrA4gaB5abv_3MEmO4knf3nvrNM9iP6eTPS8vvy9IFaCoAo20EyVxmAWxTryBXwmdINPJ6psdWQHk%3D")
                    .execute()
                    .body();

            if (html.equals("")) {
//                // 创建HttpClient对象
//                HttpClient httpClient = HttpClientBuilder.create().build();
//                // 创建HttpGet对象，设置请求的URL
//                HttpGet httpGet = new HttpGet("https://cq.ke.com/xiaoqu/rs");
//
//                // 执行HTTP请求，获取HTTP响应
//                HttpResponse httpResponse = httpClient.execute(httpGet);
//
//                // 获取HTTP响应的实体内容
//                HttpEntity httpEntity = httpResponse.getEntity();
//                String responseBody = EntityUtils.toString(httpEntity);
//                // 获取HTTP响应的状态码
//                int statusCode = httpResponse.getStatusLine().getStatusCode();
//                // 判断状态码是否为重定向
//                if (statusCode == 301 || statusCode == 302) {
//                    // 获取重定向的URL
//                    String redirectUrl = httpResponse.getFirstHeader("Location").getValue();
//                    // 打印重定向返回地址
//                    System.out.println("重定向返回地址：" + redirectUrl);
//                    // 是重定向
//                    // 进行下一步操作
//                } else {
//                    // 不是重定向
//                    // 处理其他逻辑
//                }

                // 使用Jsoup解析HTML
                //Document doc = Jsoup.parse(html);
            }

            // 使用Jsoup解析HTML
            Document doc = Jsoup.parse(html);

            // 获取页面中第一个<div>元素属性
            Element firstDiv = doc.getElementsByClass("totalPrice").first();
            Element classValue = firstDiv.getElementsByTag("span").first();

            // 输出结果
            return classValue.html();
        } catch (Exception e) {
            //log.error("获取到数据异常", e);
        }
        return "";
    }

    /**
     * 获取安居客租房网搜索结果
     *
     * @param param 要搜索的关键字
     * @return 房源总价格
     */
    public static String  getAnJuKeHousingResForSearch(String param) {
        try {
            // 从URL获取HTML内容

            String html = HttpUtil.createGet("https://chongqing.anjuke.com/community/?kw=" + param).execute().body();

            // 使用Jsoup解析HTML
            Document doc = Jsoup.parse(html);
            System.out.println(html);
            // 获取页面中第一个<div>元素属性
//            Element firstDiv = doc.getElementsByClass("community-price").last();
//            Element classValue = firstDiv.getElementsByTag("strong").first();
            Elements elements = doc.select("community-price");

            // 输出结果
            return elements.html();
        } catch (Exception e) {
            //log.error("获取到数据异常", e);
        }
        return "";
    }

    public static void main(String[] args) {
        System.out.println(getBkeHousingResForSearch2("嘉悦广场"));
    }

}
